package com.jing.cloud.service.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.collect.Maps;
import com.jing.cloud.service.bean.ServiceBean;
import com.jing.cloud.service.bean.ServiceDatasource;
import com.jing.cloud.service.bean.ServiceTable;
import com.jing.cloud.service.util.keygen.DefaultKeyGenerator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


@Configuration
@PropertySource("classpath:config/application-config.properties")
public class DataSourceConfig {

    @Value("${db.driver}")
    private String driver;
    @Value("${db.url}")
    private String url;
    @Value("${db.username}")
    private String username;
    @Value("${db.password}")
    private String password;
    @Value("${db.testWhileIdle:false}")
    private boolean testWhileIdle;
    @Value("${db.validationQuery:SELECT 1}")
    private String validationQuery;
    @Value("${db.initialSize:10}")
    private int initialSize;
    @Value("${db.minIdle:5}")
    private int minIdle;
    @Value("${db.maxActive:200}")
    private int maxActive;

    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setTestWhileIdle(testWhileIdle);
        dataSource.setValidationQuery(validationQuery);
        dataSource.setInitialSize(initialSize);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxActive(maxActive);
        try {
            dataSource.setFilters("stat,wall");
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return dataSource;
    }

    //    @Bean
    public NamedParameterJdbcTemplate namedParameterJdbcTemplate(DataSource dataSource) {
        return new NamedParameterJdbcTemplate(dataSource);
    }

    @Bean
    public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {

        ServiceBean serviceBean = serviceBean();


        DataSource dataSource = DynamicDataSource.shardingDataSource(serviceBean);
        return new NamedParameterJdbcTemplate(dataSource);
    }


    public static ServiceBean serviceBean() {
        ServiceBean sbean = new ServiceBean();
        sbean.setServiceName("im");
        sbean.setVersion("1.0.0");
        sbean.setId(genKey());
        sbean.setShardingShowSql(true);
        sbean.setShardingMetricsEnable(false);
        sbean.setShardingmetricsMillisPeriod(100000L);
        sbean.forCreate();
        List<ServiceDatasource> ds = new ArrayList<>();
        sbean.setDs(ds);
        for (int i = 0; i < 2; i++) {
            String dsName = "user_0" + i;
            ServiceDatasource sds = new ServiceDatasource();
            sds.setId(genKey());
            sds.setServiceId(sbean.getId());
            sds.setDriver("com.mysql.jdbc.Driver");
            sds.setUrl("jdbc:mysql://127.0.0.1:3306/" + dsName + "?useUnicode=true&characterEncoding=utf8&useSSL=false");
            sds.setName(dsName);
            sds.setUsername("root");
            sds.setPwd("le");
            sds.setTestWhileIdle(true);
            sds.setValidationQuery("select 1");
            sds.setInitialSize(5);
            sds.setMinIdle(5);
            sds.setMaxActive(50);
            sds.forCreate();
            ds.add(sds);
        }

        List<ServiceTable> stables = new ArrayList<>();
        sbean.setTables(stables);
        Map<String, String> map = Maps.newHashMap();
        map.put("user", "id");
        map.put("account", "userId");
        map.put("password", "userId");
        map.put("ticket", "ticketHash");
        map.put("login_record", "userId");
        map.put("message", "roomShard");
        map.put("message_cursor", "userId");
        map.put("user_message", "userId");
        map.put("buddy", "userId");
        map.put("group", "id");
        map.put("group_member", "userId");
        map.put("user_message", "userId");


        for (String tableName : map.keySet()) {
            String shard = map.get(tableName);
            ServiceTable t = new ServiceTable();
            t.setId(genKey());
            t.setServiceId(sbean.getId());
            t.setLogicName(tableName);
            t.setTableShardingKey(shard);
            t.setTableSharding(5);
            t.setDataSourceShardingKey(shard);
            t.setDataSourceSharding(2);
            t.forCreate();
            stables.add(t);

        }
        return sbean;
    }


    private static long genKey() {
        return DefaultKeyGenerator.getInstance().generateKey().longValue();
    }
}
